package com.xbongbong.paas.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.constant.EsNormalConstant;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.enums.ComboTypeEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.field.LinkListPojo;
import com.xbongbong.paas.field.LinkedAttrPoJo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.DetailTabPojo;
import com.xbongbong.paas.pojo.DetailTitlePojo;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.WorkFlowPojo;
import com.xbongbong.paas.pojo.dto.FormDataAddGetDTO;
import com.xbongbong.paas.pojo.dto.ParseSingleRowDataDTO;
import com.xbongbong.paas.pojo.dto.UserAndDepartmentGetDTO;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.pojo.vo.UserAndDepartmentGetVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.PaasAppService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.RegexUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.DepartmentVO;
import com.xbongbong.paas.toolbox.wrap.RoleSimpleVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.TitleUtil;
import com.xbongbong.parent.parse.data.BaseFormDataLinkDataHelp;
import com.xbongbong.parent.parse.data.FormDataListAnalysisDataHelp;
import com.xbongbong.parent.parse.data.LinkDataHelp;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.domain.entity.ChartLimitEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.form.pojo.TopPermissionsPoJo;
import com.xbongbong.pro.formdata.pojo.dto.FormDataDetailDTO;
import com.xbongbong.pro.formdata.pojo.dto.LinkDataDTO;
import com.xbongbong.pro.formdata.pojo.dto.LinkQueryDTO;
import com.xbongbong.pro.formdata.pojo.vo.LinkQueryVO;
import com.xbongbong.pro.formexplain.pojo.DefaultLinkInfoPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.permission.pojo.dto.VerifyAddPermissionDTO;
import com.xbongbong.pro.statistic.enums.ChartLimitTypeEnum;
import com.xbongbong.pro.statistic.model.ChartLimitModel;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.help.SaasGetHelp;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.service.FundSetService;
import com.xbongbong.saas.service.MobileDetailService;
import com.xbongbong.saas.service.WorkOrderFormService;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.help.ProPermissionHelp;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.workflow.model.WorkflowModel;
import com.xbongbong.workflow.model.WorkflowTaskModel;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery;

/**
 * @author 吴峰
 * @version v1.0
 * @date 2019/5/30 19:24
 * @since v1.0
 */
@Component
public class PaasFormHelp {

    private static final Logger LOG = LoggerFactory.getLogger(PaasFormHelp.class);

    @Resource
    private SaasGetHelp saasGetHelp;
    @Resource
    private MobileDetailService mobileDetailService;
    @Resource
    private UserHelp userHelp;
    @Resource
    private FormDataListAnalysisDataHelp formDataListAnalysisDataHelp;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private LinkListHelp linkListHelp;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PaasAppService paasAppService;
    @Resource
    private WorkOrderFormService workOrderFormService;
    @Resource
    private LinkDataHelp linkDataHelp;
    @Resource
    private UserModel userModel;
    @Resource
    private FundSetService fundSetService;
    @Resource
    private OwnerAndCoUserHelp ownerAndCoUserHelp;
    @Resource
    private WorkflowModel workflowModel;
    @Resource
    private WorkflowTaskModel workflowTaskModel;
    @Resource
    private BusinessUserTeamHelp businessUserTeamHelp;
    @Resource
    private BaseFormDataLinkDataHelp baseFormDataLinkDataHelp;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private ChartLimitModel chartLimitModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;

    /**
     * 拼装关联查询和关联数据的条件和搜索字段
     * @param linkQueryDTO
     * @param boolQueryBuilder es条件实体
     */
    public LinkQueryVO getLinkBoolQueryBuilder(LinkQueryDTO linkQueryDTO, BoolQueryBuilder boolQueryBuilder) throws XbbException {
        LinkQueryVO linkQueryVO = new LinkQueryVO();
        String corpid = linkQueryDTO.getCorpid();
        List<LinkedAttrPoJo> fieldList = linkQueryDTO.getFieldList();
        LinkInfoPojo linkInfoPojo = linkQueryDTO.getLinkInfo();
        List<FieldAttrEntity> explainList = new ArrayList<>();
        Map<String, FieldAttrEntity> explainMap = linkQueryDTO.getExplainMap();
        Object value = linkQueryDTO.getComplianceData();
        Set<String> resultFieldList = new HashSet<>();
        List<String> subFieldList = new ArrayList<>();
        for (LinkedAttrPoJo item : fieldList) {
            if (explainMap.containsKey(item.getAttr())) {

                FieldAttrEntity fieldAttrEntity = explainMap.get(item.getAttr());
                if (Objects.equals(linkInfoPojo.getLinkSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                    List<ItemPoJo> itemPoJoList = proFormHelp.getItem(fieldAttrEntity, linkInfoPojo.getLinkBusinessType(), corpid, linkInfoPojo.getLinkFormId());
                    fieldAttrEntity.setItems(itemPoJoList);
                }
                if (Objects.equals(FieldTypeEnum.SUB_FORM.getType(), fieldAttrEntity.getFieldType())) {
                    subFieldList.add(item.getAttr());
                } else {
                    resultFieldList.add(item.getAttr());
                }
                fieldAttrEntity.setAttrName(fieldAttrEntity.getAttrName());
                explainList.add(fieldAttrEntity);
                explainMap.put(item.getAttr(), fieldAttrEntity);
                if (value != null && StringUtil.isNotEmpty(value.toString())) {
                    FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(item.getFieldType());
                    switch (fieldTypeEnum) {
                        case ADDRESS:
                            boolQueryBuilder.should(matchPhraseQuery("data." + item.getAttr() + StringConstant.POINT + BusinessConstant.PROVINCE, value));
                            boolQueryBuilder.should(matchPhraseQuery("data." + item.getAttr() + StringConstant.POINT + BusinessConstant.CITY, value));
                            boolQueryBuilder.should(matchPhraseQuery("data." + item.getAttr() + StringConstant.POINT + BusinessConstant.DISTRICT, value));
                            boolQueryBuilder.should(matchPhraseQuery("data." + item.getAttr() + StringConstant.POINT + BusinessConstant.ADDRESS, value));
                            break;
                        //目前只有阶段推进器的阶段流程id是LONG类型，用于查询阶段版本用，该字段不显示，所以不参与查询
                        case LONG:
                            break;
                        case NUM:
                            if (StringUtil.isDouble(value.toString())) {
                                boolQueryBuilder.should(matchPhraseQuery("data." + item.getAttr(), Double.valueOf(value.toString())));
                            } else if (StringUtil.isNumeric(value.toString())) {
                                boolQueryBuilder.should(matchPhraseQuery("data." + item.getAttr(), Long.valueOf(value.toString())));
                            }
                            break;
                        case SERIALNO:
                            boolQueryBuilder.should(matchPhraseQuery(item.getAttr(), value));
                            break;
                        case DATETIME:
                            // 日期不模糊搜索
                            break;
                        case COMBO:
                        case RADIO_GROUP:
                        case CHECKBOX_GROUP:
                        case COMBO_CHECK:
                            if (Objects.equals(ComboTypeEnum.CUSTOM.getType(), fieldAttrEntity.getComboType())) {
                                List<ItemPoJo> itemList = fieldAttrEntity.getItems();
                                if (Objects.nonNull(itemList)) {
                                    itemList.forEach(itemValue->{
                                        if (itemValue.getText().contains(value.toString())) {
                                            boolQueryBuilder.should(matchPhraseQuery("data." + item.getAttr(), itemValue.getValue()));
                                        }
                                    });
                                }
                            } else {
                                boolQueryBuilder.should(matchPhraseQuery("data." + item.getAttr(), value));
                            }
                            break;
                        case STAGE_THRUSTER:
                            //目前支持检索当前启用阶段版本
                            List<ItemPoJo> itemList = proFormHelp.getEnableStageComboItems(linkInfoPojo.getLinkSaasMark(), linkInfoPojo.getLinkBusinessType(), corpid, linkInfoPojo.getLinkFormId());
                            if (Objects.nonNull(itemList)) {
                                itemList.forEach(itemValue->{
                                    if (itemValue.getText().contains(value.toString())) {
                                        boolQueryBuilder.should(matchPhraseQuery("data." + item.getAttr() + ".keyword", itemValue.getValue()));
                                    }
                                });
                            }
                        default:
                            boolQueryBuilder.should(matchPhraseQuery("data." + item.getAttr(), value));
                            break;
                    }
                    boolQueryBuilder.minimumShouldMatch(EsNormalConstant.MINI_MUM_SHOULD_MATCH);
                }
            }
        }
        linkQueryVO.setFieldList(new ArrayList<>(resultFieldList));
        linkQueryVO.setSubFieldList(subFieldList);
        linkQueryVO.setExplainList(explainList);
        linkQueryVO.setExplainMap(explainMap);
        return linkQueryVO;
    }

    /**
     * 基于com.xbongbong.pro.statistic.service.impl.ChartLimitServiceImpl#getCkFlag()方法
     *
     * @return boolean true-ck环境 false-非ck环境
     * @author zyy
     * @date 2023/3/24
     * @version v1.0
     */
    public boolean getCkFlag(){
        String corpId = "0";
        String basePackageStr = paasRedisHelper.getValue(RedisPrefixConstant.SWITCH_CK_KEY_ENV, corpId);
        if (!StringUtil.isEmpty(basePackageStr)) {
            if(Objects.equals("1",basePackageStr)){
                return true;
            }
            return false;
        }
        ChartLimitEntity chartLimit = chartLimitModel.getByType(ChartLimitTypeEnum.CHART_DATA_SOURCE_LIMIT.getCode(), corpId);
        boolean flag = false;
        int flagNum = 0;
        if(chartLimit !=null && Objects.equals(chartLimit.getDel(),DelEnum.NORMAL.getDel())){
            flagNum = 1;
            flag = true;
        }
        paasRedisHelper.setValue(RedisPrefixConstant.SWITCH_CK_KEY_ENV, corpId, flagNum, RedisConstant.LONG_DURATION);
        return flag;
    }

    /**
     * 根据表单设置的摘要信息，进行摘要数据梳理
     * 我能怎么办，还要套层saas的摘要
     * @param paasFormEntityExt 表单
     * @param explainMap 字段
     * @param paasFormDataEntityExt 数据
     * @return
     * @throws XbbException
     */
    public List<SummaryDataPoJo> getSummaryList(PaasFormEntityExt paasFormEntityExt, Map<String, FieldAttrEntity> explainMap,
                                                PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException {
        JSONArray jsonArray = JSONArray.parseArray(paasFormEntityExt.getSummary());
        JSONObject data = paasFormDataEntityExt.getData();
        List<SummaryDataPoJo> summaryList = ExplainUtil.getSummaryList(jsonArray, data, explainMap,
                 paasFormDataEntityExt);
        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), paasFormEntityExt.getSaasMark())) {
            saasGetHelp.getSaasSummary(summaryList, paasFormEntityExt.getBusinessType(), paasFormDataEntityExt);
            // 将星级转换掉
            mobileDetailService.transferKeyToShowValue(paasFormEntityExt.getCorpid(), summaryList, paasFormEntityExt.getBusinessType());
        }
        return summaryList;
    }

    /**
     * 作为web的标题和摘要，功能和详情的一样
     * @param formDataDetailDTO
     * @param handlerExplainVO
     * @param detailTitlePojo
     * @param secondTitle
     * @param paasFormDataEntityExt
     * @param paasFormEntityExt
     * @throws XbbException
     */
    public void getWebTitleAndSummary(FormDataDetailDTO formDataDetailDTO, HandlerExplainVO handlerExplainVO, DetailTitlePojo detailTitlePojo, JSONArray secondTitle,
                                     PaasFormDataEntityExt paasFormDataEntityExt, PaasFormEntityExt paasFormEntityExt) throws XbbException {
        List<FieldAttrEntity> explainList = handlerExplainVO.getHeadList();
        // 和 表单详情重复操作
        // ---- 获取用户和部门容器start
        UserAndDepartmentGetDTO userAndDepartmentGetDTO = new UserAndDepartmentGetDTO();
        BeanUtil.copyProperties(formDataDetailDTO, userAndDepartmentGetDTO);
        userAndDepartmentGetDTO.setExplainList(explainList);
        UserAndDepartmentGetVO userAndDepartmentGetVO = userHelp.getUserDepartmentMap(userAndDepartmentGetDTO, Constant.ONE);
        Map<String, UserEntity> userMap = userAndDepartmentGetVO.getUserMap();
        Map<String, DepartmentEntity> departmentMap = userAndDepartmentGetVO.getDepartmentMap();
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(JSONObject.toJSONString(handlerExplainVO.getHeadList()), null);
        //  获取用户和部门容器 解析paas的特殊数据 end
        JSONObject data = paasFormDataEntityExt.getData();
        // 设置系统字段
        // 设置创建者
        data.put(FieldTypeEnum.ADDTIME.getAlias(), paasFormDataEntityExt.getAddTime());
        data.put(FieldTypeEnum.UPDATETIME.getAlias(), paasFormDataEntityExt.getUpdateTime());
        data.put(FieldTypeEnum.SERIALNO.getAlias(), paasFormDataEntityExt.getSerialNo());
        data.put(FieldTypeEnum.CREATORID.getAlias(), paasFormDataEntityExt.getCreatorId());
        // 设置协同人和负责人
        userHelp.setOwnerAndCoUser(data, paasFormDataEntityExt, formDataDetailDTO.getSaasMark(), formDataDetailDTO.getBusinessType(), userMap);
        ParseSingleRowDataDTO parseSingleRowDataDTO = new ParseSingleRowDataDTO();
        BeanUtil.copyProperties(formDataDetailDTO, parseSingleRowDataDTO);
        parseSingleRowDataDTO.setDataJsonObject(data);
        parseSingleRowDataDTO.setExplainMap(explainMap);
        parseSingleRowDataDTO.setUserMap(userMap);
        parseSingleRowDataDTO.setDepartmentMap(departmentMap);
        // 解析数据
        ParseSingleRowDataVO parseSingleRowDataVO = formDataListAnalysisDataHelp.parseSingleRowData(parseSingleRowDataDTO);
        if (Objects.isNull(parseSingleRowDataVO)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PARSE_SINGLE_ROW_DATA_FAILED);
        }
        // 解析摘要
        data = parseSingleRowDataVO.getResult();
        paasFormDataEntityExt.setData(data);
        List<SummaryDataPoJo> summaryList = getSummaryList(paasFormEntityExt, explainMap, paasFormDataEntityExt);
        // 解析标题
        List<FormTitlePoJo> formTitleList = ExplainUtil.getFormTitle(JSONArray.parseArray(paasFormEntityExt.getCustomTitle()), explainMap, data, explainList, paasFormDataEntityExt);
        summaryList.forEach(item->{
            JSONObject jsonObject = ExplainUtil.getSecondTitleObj(false, item.getAttrName(), StringUtils.join(item.getValue(), "、"));
            secondTitle.add(jsonObject);
        });
        String title = TitleUtil.getTitle(formTitleList);
        detailTitlePojo.setName(title);
    }

    /**
     * 拼装关联列表的tab，获取最新的表单名称
     * @param linkList 关联列表
     * @param corpid 公司id
     */
    public void getLinkList(List<LinkListPojo> linkList, String corpid) throws XbbException {
        linkListHelp.getLinkList(linkList, corpid);
    }

    /**
     * 获取关联列表的tab
     * @param linkList 关联列表
     * @param detailTabList 已有的tab
     * @param userVO 用户信息
     */
    public void getLinkListTab(List<LinkListPojo> linkList, List<DetailTabPojo> detailTabList, UserVO userVO) {
        linkListHelp.getLinkListTab(linkList, detailTabList, userVO);
    }

    /**
     * 获取关联列表的操作按钮
     * @param linkList 关联列表
     * @param workFlowList 操作按钮
     * @param userVO 用户
     */
    public void getLinkListAddButton(List<LinkListPojo> linkList, List<WorkFlowPojo> workFlowList, UserVO userVO, PlatFormEnum platForm) {
        workFlowList.addAll(linkListHelp.getLinkListAddButton(linkList, userVO, platForm));
    }

    /**
     * 设置手机端的关联列表的按钮
     * @param topPermissions
     * @param linkList
     * @param loginUser
     * @return void
     * @author 吴峰
     * @date 2020/10/13 16:15
     * @throws XbbException
     */
    public void setMobileLinkListButton(List<TopPermissionsPoJo> topPermissions, List<LinkListPojo> linkList, UserVO loginUser) {
        topPermissions.addAll(linkListHelp.setMobileLinkListButton( linkList, loginUser));
    }



    public List<ButtonPojo> getAddPermission(LinkListPojo linkListPojo, UserVO userVO) {
        Set<Long> idSet = ProPermissionHelp.getPaasCreateMenuIdSet(userVO.getPaasPermissions());
        // 上部按钮权限
        List<ButtonPojo> topPermissionList = new ArrayList<>();
        Boolean isAdmin = userVO.isAdminOrBoss();
        if (idSet.contains(linkListPojo.getLinkMenuId()) || isAdmin) {
            ButtonPojo button = new ButtonPojo();
            button.setAttr(SaasButtonEnum.ADD.getAttr());
            button.setValue(SaasButtonEnum.ADD.getValue());
            button.setType(SaasButtonEnum.ADD.getType());
            topPermissionList.add(button);
        }
        return topPermissionList;
    }

    /**
     * 设置默认的关联数据
     * @param explainList
     * @param formDataAddGetDTO
     * @param handlerExplainVO
     * @return void
     * @author 吴峰
     * @date 2021/3/10 9:31
     * @throws XbbException
     */
    public void setDefaultLinkData(List<FieldAttrEntity> explainList, FormDataAddGetDTO formDataAddGetDTO, HandlerExplainVO handlerExplainVO) throws XbbException {
        linkDataHelp.setDefaultLinkData(explainList, formDataAddGetDTO, handlerExplainVO);
    }



    public boolean haveNoPermission(UserVO userVO, List<OptionalRangeEntity> permissions) {
        Set<String> roleList = new HashSet<>();
        Set<Long> departmentSet = new HashSet<>();
        Set<String> userList = new HashSet<>();
        for(OptionalRangeEntity optionalRangeEntity: permissions) {
            if(Objects.equals(optionalRangeEntity.getProperty(), OptionalRangeEnum.DEPT.getValue())){
                if (RegexUtil.isNumber(optionalRangeEntity.getId())) {
                    departmentSet.add(Long.valueOf(optionalRangeEntity.getId()));
                }
            } else if (Objects.equals(optionalRangeEntity.getProperty(), OptionalRangeEnum.ROLE.getValue())){
                roleList.add(optionalRangeEntity.getId());
            } else if (optionalRangeEntity.getProperty().equals(OptionalRangeEnum.USER.getValue())){
                userList.add(optionalRangeEntity.getId());
            }
        }
        List<Long> deptList = departmentModel.getSubDepIdList(userVO.getCorpid(), departmentSet);
        deptList.addAll(departmentSet);
        String userId = userVO.getUserId();
        Set<RoleSimpleVO> roleSimpleVOSet = userVO.getRoleSet();
        Set<DepartmentVO> departmentVOSet = userVO.getDepSet();
        if (!userList.isEmpty()) {
            if (userList.contains(userId)) {
                return false;
            }
        }
        if (!roleList.isEmpty()) {
            for (RoleSimpleVO roleSimpleVO : roleSimpleVOSet) {
                if (roleList.contains(roleSimpleVO.getId().toString())) {
                    return false;
                }
            }
        }
        if (!deptList.isEmpty()) {
            for (DepartmentVO departmentVO : departmentVOSet) {
                if (deptList.contains(departmentVO.getId())) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 获取创建人和协同人、负责人，为高级规则可见可编辑做准备
     * @param handlerExplainDTO
     * @param businessType
     * @param subBusinessType
     * @param paasFormDataEntity
     * @throws XbbException
     */
    public JSONObject getOwnerIdAndCoUserId(HandlerExplainDTO handlerExplainDTO, Integer saasMark, Integer businessType,
                                            Integer subBusinessType, PaasFormDataEntityExt paasFormDataEntity,Map<String, UserEntity> userMap) throws XbbException {
        // 获取协同人和负责人
        return ownerAndCoUserHelp.getOwnerIdAndCoUserId(handlerExplainDTO, saasMark, businessType, paasFormDataEntity, userMap, DelEnum.NORMAL.getDel());
    }

    /**
     * 获取关联数据和关联查询的关联表单
     * @author 吴峰
     * @date 2019/7/4 9:52
     * @param explainList
     * @param corpid
     * @return java.util.Map<java.lang.Long,com.xbongbong.paas.domain.entity.PaasFormExplainEntity>
     * @throws XbbException 业务异常
     */
    public Map<Long, PaasFormExplainEntity> getLinkFormExplain(List<FieldAttrEntity> explainList, String corpid) throws XbbException {
        return proFormHelp.getLinkFormExplain(explainList, corpid);
    }

    /**
     * 获取关联数据和关联查询的关联表单
     * @author 吴峰
     * @date 2019/7/4 9:52
     * @param explainList
     * @param corpid
     * @return java.util.Map<java.lang.Long,com.xbongbong.paas.domain.entity.PaasFormExplainEntity>
     * @throws XbbException 业务异常
     */
    public Map<Long, WorkOrderExplainEntity> getWorkOrderLinkFormExplain(List<FieldAttrEntity> explainList, String corpid) throws XbbException {
        return proFormHelp.getWorkOrderLinkFormExplain(explainList, corpid);
    }

    /**
     * 根据表单id获取新建的权限按钮
     * @param verifyAddPermissionDTO
     * @param appId
     * @param formId
     * @return
     * @throws XbbException
     */
    public List<ButtonPojo> getAddButton(VerifyAddPermissionDTO verifyAddPermissionDTO, Long appId, Long formId) throws XbbException {
        String corpid = verifyAddPermissionDTO.getCorpid();
        List<ButtonPojo> buttonList = new ArrayList<>();
        Integer businessType = verifyAddPermissionDTO.getBusinessType();
        Long menuId = verifyAddPermissionDTO.getMenuId();
        boolean enable = paasAppService.validateAppEnable(appId, "", verifyAddPermissionDTO.getSaasMark(), corpid);
        Integer distributorMark = verifyAddPermissionDTO.getDistributorMark();
        if (enable) {
            PaasMenuEntity paasMenuEntity = paasMenuModel.getByKey(menuId, corpid);
            if (Objects.isNull(paasMenuEntity)) {
                LOG.error("menu empty：menuId"+menuId + "--corpid=" +corpid);
                return new ArrayList<>();
            }
            enable = Objects.equals(1, paasMenuEntity.getEnable());
            if (enable) {
                if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)) {
                    enable = workOrderFormService.getFormPermissionByFormId(verifyAddPermissionDTO.getLoginUser(), formId);
                }else {
                    PaasFormEntity paasFormEntity = proFormHelp.getPaasForm(formId, businessType, corpid);
                    if (Objects.isNull(paasFormEntity)) {
                        LOG.error("form empty：formId="+menuId + "--corpid=" +corpid);
                        return new ArrayList<>();
                    }
                    distributorMark = paasFormEntity.getDistributorMark();
                    enable = Objects.equals(1, paasFormEntity.getEnable());
                    boolean isMultiTemplate = Objects.equals(XbbRefTypeEnum.CONTRACT.getCode(), businessType) || Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType);
                    if (enable && isMultiTemplate) {
                        List<OptionalRangeEntity> optionalRangeList = JSONObject.parseArray(paasFormEntity.getPermission(), OptionalRangeEntity.class);
                        // 判断合同和客户多模板的权限
                        if (CollectionsUtil.isNotEmpty(optionalRangeList)) {
                            enable = !haveNoPermission(verifyAddPermissionDTO.getLoginUser(), optionalRangeList);
                        }
                    }
                }
            }
        }
        //资金这边需要加特殊逻辑，关联应收款新建的时候如果当前模式是非手动创建应收模式则没有新增按钮
        Long nowModelType = fundSetService.getModelType(corpid,XbbRefTypeEnum.CRM);
        if (!Objects.equals(nowModelType, ModelTypeEnum.PLAN.getCode()) && Objects.equals(businessType, XbbRefTypeEnum.PAYMENT.getCode())) {
            return buttonList;
        }
        if (ProPermissionHelp.getAddPermission(verifyAddPermissionDTO) && enable) {
            ButtonPojo buttonPojo = new ButtonPojo();
            buttonPojo.setAttr(SaasButtonEnum.ADD.getAttr());
            buttonPojo.setValue(SaasButtonEnum.ADD.getValue());
            buttonPojo.setType(SaasButtonEnum.ADD.getType());
            buttonPojo.setDistributorMark(distributorMark);
            buttonList.add(buttonPojo);
        }
        return buttonList;
    }

    /**
     * 校验表单下是否有工作流以及工作流任务
     * @param corpid
     * @param appId
     * @param menuId
     * @param formId
     * @throws XbbException
     */
    public void validateFormHasWorkflow(String corpid, Long appId, Long menuId, Long formId) throws XbbException {
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("appId", appId);
        params.put("menuId", menuId);
        params.put("formId", formId);
        params.put(StringConstant.CORPID, corpid);
        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        Integer count = workflowModel.getEntitysCount(params);
        if (count > 0) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_WORKFLOW_IS_ENABLE);
        }
        params.clear();
        params.put(StringConstant.CORPID, corpid);
        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        params.put("appId", appId);
        params.put("menuId", menuId);
        params.put("formId", formId);
        count = workflowTaskModel.getEntityCount(params);
        if (count > 0) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.HAS_PROCESS_DATA);
        }

    }


    /**
     * @Author mingliang
     * @Description 获取负责人
     * @Date 2022/4/1 15:32
     * @param userIdList
     * @param dataId
     * @param corpid
     * @param businessType
     * @param isPublic
     **/
    public String getOwnerName(Set<String> userIdList, Long dataId, String corpid, Integer businessType, Boolean isPublic) {
        Map<Long, List<String>> mainUserMap = new HashMap<>();
        businessUserTeamHelp.getUserIdMapSetShow(userIdList, Collections.singletonList(dataId), corpid, businessType, isPublic, mainUserMap, new HashMap<>(), DelEnum.NORMAL.getDel());
        List<String> mainUserIdList = mainUserMap.get(dataId);
        List<UserEntity> byUserIdIn = userModel.getByUserIdIn(corpid, mainUserIdList);
        if (CollectionsUtil.isEmpty(byUserIdIn)) {
            return "";
        }
        StringBuffer owner = new StringBuffer();
        byUserIdIn.forEach(e -> {
            owner.append(e.getName()).append(",");
        });
        return owner.toString();
    }

    /**
     * 关联数据或者关联数据多选获取数据联动值
     * @param userAndDepartmentGetDTO
     * @param defaultLinkInfo
     * @param fieldAttrEntity
     * @param userMap
     * @param departmentMap
     * @return
     * @throws XbbException
     */
    public JSONArray setRelyLinkData(UserAndDepartmentGetDTO userAndDepartmentGetDTO, DefaultLinkInfoPojo defaultLinkInfo, FieldAttrEntity fieldAttrEntity, Map<String, UserEntity> userMap, Map<String, DepartmentEntity> departmentMap) throws XbbException {
        if (Objects.isNull(fieldAttrEntity) || Objects.isNull(fieldAttrEntity.getLinkInfo())) {
            return null;
        }
        LinkInfoPojo linkInfoPojo = fieldAttrEntity.getLinkInfo();
        if (CollectionsUtil.isNotEmpty(linkInfoPojo.getCondition())) {
            // 如果有条件的话，需要手动选择关联数据
            return null;
        }
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(userAndDepartmentGetDTO.getCorpid(), defaultLinkInfo.getBusinessType(), defaultLinkInfo.getSaasMark());
        // 查询本表单的数据
        // PaasFormDataEntityExt item = paasEsModel.getByKey(defaultLinkInfo.getDataId(), formDataAddGetDTO.getCorpid(), indexTypeEnum, null);
        List<Long> dataIdList = new ArrayList<>();
        Object dataId = defaultLinkInfo.getDataId();
        if (dataId instanceof Number) {
            dataIdList.add(Long.parseLong(dataId.toString()));
        } else if (dataId instanceof List) {
            dataIdList = JSON.parseArray(JSON.toJSONString(dataId), Long.class);
        } else {
            return null;
        }
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = paasEsModel.getByIdList(dataIdList, userAndDepartmentGetDTO.getCorpid(), defaultLinkInfo.getSaasMark(), defaultLinkInfo.getBusinessType(), null, indexTypeEnum);
        if (CollectionsUtil.isEmpty(paasFormDataEntityExtList)) {
            // fix-bug：32543 加个判断避免下面空指针错误
            return null;
        }
        Map<String, PaasFormDataEntityExt> formDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        paasFormDataEntityExtList.forEach(item -> {
            String value = item.getDataId().toString();
            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), defaultLinkInfo.getSaasMark())) {
                value = defaultLinkInfo.getBusinessType() + "_" + value;
            }
            formDataMap.put(value, item);
        });

        Map<String, PaasFormExplainEntity> formExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, WorkOrderExplainEntity> workOrderFormExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), linkInfoPojo.getLinkBusinessType())) {
            WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainModel.getByFormId(linkInfoPojo.getLinkFormId(), userAndDepartmentGetDTO.getCorpid());
            workOrderFormExplainMap.put(linkInfoPojo.getLinkFormId().toString(), workOrderExplainEntity);
        } else {
            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(linkInfoPojo.getLinkFormId(), userAndDepartmentGetDTO.getCorpid());
            formExplainMap.put(linkInfoPojo.getLinkFormId().toString(), paasFormExplainEntity);
        }

        if (userMap.isEmpty()) {
            userMap = userHelp.getUserMap(userAndDepartmentGetDTO);
        }
        if (departmentMap.isEmpty()) {
            departmentMap = userHelp.getDepartmentMap(userAndDepartmentGetDTO);
        }
        // 设置主键字段
        linkDataHelp.setLinkKey(fieldAttrEntity);
        LinkDataDTO linkDataDTO = new LinkDataDTO();
        BeanUtil.copyProperties(userAndDepartmentGetDTO, linkDataDTO);

        JSONArray linkDataResult = new JSONArray();
        for (Long linkDataId : dataIdList) {
            JSONObject jsonObject = baseFormDataLinkDataHelp.getLinkData(fieldAttrEntity, formDataMap, linkDataId.toString(), formExplainMap, workOrderFormExplainMap, userMap, departmentMap, linkDataDTO, fieldAttrEntity.getLinkInfo().getLinkedAttr());
            if(jsonObject == null){
                jsonObject = new JSONObject();
            }
            JSONObject linkDataJsonObject = new JSONObject();
            linkDataJsonObject.put("dataId", linkDataId);
            linkDataJsonObject.put("id", linkDataId);
            linkDataJsonObject.put("data", jsonObject);
            linkDataResult.add(linkDataJsonObject);
        }

        return linkDataResult;
    }

}
